import datetime
import json
import random

from django.db.models import Q
from django.http import JsonResponse
from django.shortcuts import render, redirect, reverse
from django.views import View
from pure_pagination import Paginator, PageNotAnInteger
from asgiref.sync import async_to_sync
from channels.layers import get_channel_layer

from Jv.settings import RTMP_ADDRESS, STREAM_IP
from utils.delete_stream import delete_stream
from utils.get_md5 import get_md5
from .forms import RoomPicForm
from .models import LiveRoom, Label, SonLabel
from ..user.models import UserProfile


# Create your views here.


class AllLiveView(View):
    """所有直播"""

    def get(self, request):
        data = {}

        # 获取分区直播，没有分区，则全部直播
        live_list = LiveRoom.objects.filter(is_active=True, is_open=True).order_by('-hot_num')
        live_type = request.GET.get('type')
        if live_type:
            try:
                data['type'] = int(live_type)
            except:
                return redirect(reverse('all_live'))
            live_list = LiveRoom.objects.filter(label__father_label__id=live_type, is_active=True,
                                                is_open=True).order_by('-hot_num')
            if not live_list:
                live_list = LiveRoom.objects.filter(is_active=True, is_open=True).order_by('-hot_num')
            # 子标签
            son_label = SonLabel.objects.filter(father_label_id=live_type)
            data['son_label'] = son_label

        # 所有live 分页
        try:
            page = request.GET.get('page', 1)
        except PageNotAnInteger:
            page = 1
        p = Paginator(live_list, per_page=36, request=request)
        all_live = p.page(page)
        data['all_live'] = all_live

        # 父标签
        all_flabel = Label.objects.all()[:4]
        data['all_flabel'] = all_flabel
        return render(request, 'live/live_home.html', data)


class SendMessage(View):
    """ 发送聊天室信息"""

    def post(self, request):
        # 在信息界面发送消息
        group_name = request.POST.get("group_name")
        message = request.POST.get("message")
        user_id = request.POST.get("user")
        # print(group_name, message, user)
        try:
            user = UserProfile.objects.get(id=user_id)
        except:
            return JsonResponse({
                "status": 'fail',
                'msg': '参数错误'
            })

        payload = {
            'type': 'receive',  # 这个type是有限制的，比如现在用到的就是cusumer的receive函数
            'user_id': user_id,
            'nick_name': user.nick_name if user.nick_name else user.username,
            'username': user.username,
            'message': message,  # 消息内容
        }
        channel_layer = get_channel_layer()
        async_to_sync(channel_layer.group_send)(group_name, payload)
        return JsonResponse({
            "status": "success",
            "msg": "发送成功"
        })


class SonLiveView(View):
    """展示子标签直播"""

    def get(self, request):
        data = {}
        live_type = request.GET.get('type')
        son_type = request.GET.get('son_type')

        if not son_type and not live_type:
            return redirect(reverse('all_live'))
        try:
            data['type'] = int(live_type)
            data['son_type'] = int(son_type)
        except:
            return redirect(reverse('all_live'))
        live_list = LiveRoom.objects.filter(label_id=son_type, is_active=True, is_open=True).order_by('-hot_num')

        # 父标签
        all_flabel = Label.objects.all()[:4]
        data['all_flabel'] = all_flabel

        # 子标签
        son_label = SonLabel.objects.filter(father_label_id=live_type)
        data['son_label'] = son_label

        # 所有live 分页
        try:
            page = request.GET.get('page', 1)
        except PageNotAnInteger:
            page = 1
        p = Paginator(live_list, per_page=36, request=request)
        all_live = p.page(page)
        data['all_live'] = all_live

        return render(request, 'live/son_live.html', data)


class PlayLive(View):
    """直播播放页"""

    def get(self, request):
        room_num = request.GET.get('room_num')
        try:
            lr = LiveRoom.objects.get(number=int(room_num))
        except:
            return redirect(reverse('all_live'))
        data = {}
        if lr.is_open and lr.live_key:
            play_stream = 'http://' + STREAM_IP + ':8080/live/' + lr.live_key + '.flv'
            data['play_stream'] = play_stream
        data['lr'] = lr
        return render(request, 'live/play_live.html', data)


class SearchLive(View):
    """直播搜索页"""

    def get(self, request):
        data = {}
        keyword = request.GET.get('keyword', '')
        page_name = request.GET.get('page_name', 'live')
        if keyword == '':
            return redirect(reverse('home'))
        data['page_name'] = page_name
        data['keyword'] = keyword

        live_list = LiveRoom.objects.filter(
            Q(name__icontains=keyword) | Q(user__username=keyword) | Q(user__nick_name=keyword)).order_by('-number')

        try:
            page = request.GET.get('page', 1)
        except PageNotAnInteger:
            page = 1
        p = Paginator(live_list, per_page=20, request=request)
        all_live = p.page(page)
        data['all_live'] = all_live
        return render(request, 'live/search_live.html', data)


class LiveSettingView(View):
    """直播设置页面"""

    def get(self, request):
        if not request.user.is_certificate:
            return redirect(reverse('user'))

        # 如果没有房间号随机房间号
        live_room = LiveRoom.objects.filter(user=request.user).first()
        if not live_room:
            # 分配直播间
            room_number = random.randint(10000, 99999)  # 随机分配房间号
            while LiveRoom.objects.filter(user=request.user):
                room_number = random.randint(10000, 99999)
            live_room = LiveRoom.objects.create(user=request.user, number=room_number, is_active=True)
            live_room.save()

        data = {}
        if live_room.live_stream:
            ad = RTMP_ADDRESS + live_room.live_stream
            data['ad'] = ad
        data['live_room'] = live_room

        data['key'] = live_room.live_key
        data['father_label'] = Label.objects.all()
        if live_room.label:
            data['son_label'] = SonLabel.objects.filter(father_label=live_room.label.father_label)
        return render(request, 'live/live_setting.html', data)


class GetLiveAddress(View):
    """获取推流地址"""

    def post(self, request):
        try:
            live_room = LiveRoom.objects.get(user=request.user)
        except:
            return JsonResponse({
                'status': 'fail',
                'msg': '参数错误'
            })

        md = get_md5(str(datetime.datetime.now()), request.user.username)
        # rtmp://192.168.3.41/live?token=
        ad = RTMP_ADDRESS + '?token=' + md

        # 将 token 存入数据库 connect时验证
        live_room.live_stream = '?token=' + md
        live_room.save()

        return JsonResponse({
            'status': 'success',
            'msg': ad
        })


class GetLiveKey(View):
    """获取推流密钥"""

    def post(self, request):
        # md5加密 日期 + 登陆用户名
        key = get_md5(str(datetime.datetime.now()), request.user.username)
        # 存储到数据库 在直播链接时 验证
        lr = LiveRoom.objects.get(user=request.user)
        lr.live_key = key
        lr.save()
        return JsonResponse({
            'status': 'success',
            'msg': key
        })


class ChangeLiveRoomLabel(View):
    """页面改变直播分区"""

    def post(self, request):
        father_label_id = request.POST.get('label_id')
        if not father_label_id:
            return JsonResponse({
                'status': 'fail'
            })
        son_label = SonLabel.objects.filter(father_label_id=father_label_id)
        son_label_name_list = []
        for slb in son_label:
            son_label_name_list.append(slb.name)

        if not son_label_name_list:
            return JsonResponse({
                'status': 'fail'
            })
        return JsonResponse({
            'status': 'success',
            'data': son_label_name_list
        })


class ChangeLabel(View):
    """数据库更改标签"""

    def post(self, request):
        label_name = request.POST.get('label_name')
        try:
            lb = SonLabel.objects.filter(name=label_name)
            lr = LiveRoom.objects.get(user=request.user)
        except:
            return JsonResponse({
                'status': 'fail',
                'msg': '参数错误'
            })

        lr.label = lb.first()
        lr.save()

        return JsonResponse({
            'status': 'success'
        })


class ChangeRoomName(View):
    """改名直播间名称"""

    def post(self, request):
        room_name = request.POST.get('room_name')
        if not room_name:
            return JsonResponse({
                'status': 'fail',
                'msg': '参数错误'
            })
        if len(room_name) >= 20:
            return JsonResponse({
                'status': 'fail',
                'msg': '名字过长'
            })

        # 保存名字
        lr = LiveRoom.objects.get(user=request.user)
        lr.name = room_name
        lr.save()

        return JsonResponse({
            'status': 'success'
        })


class ChangeRoomImg(View):
    """更改直播间封面"""

    def post(self, request):
        if not request.FILES:
            return JsonResponse({
                'status': 'fail',
                'msg': '参数错误'
            })

        form = RoomPicForm(request, request.FILES, instance=request.user.live_room)
        if not form.is_valid():
            return JsonResponse({
                'status': 'fail',
                'msg': '参数错误'
            })
        form.save()
        return JsonResponse({
            'status': 'success'
        })


class VerifyLiveStream(View):
    """srs回调，验证推流, connect"""

    def post(self, request):
        data = json.loads(request.body)
        # 查看 数据是否存在数据库中
        lr = LiveRoom.objects.filter(live_key=data['stream'], live_stream=data['param'], is_open=True, is_active=True)
        if not lr:
            return JsonResponse({
                'code': 1
            })
        # 必须返回0 不然失败
        return JsonResponse({
            'code': 0
        })


class OpenLive(View):
    """开始直播"""

    def post(self, request):
        try:
            lr = LiveRoom.objects.get(user=request.user, label__isnull=False, name__isnull=False,
                                      live_stream__isnull=False, live_key__isnull=False)
        except:
            return JsonResponse({
                'status': 'fail',
                'msg': '请完善直播间信息'
            })
        lr.is_open = True
        lr.save()
        return JsonResponse({
            'status': 'success'
        })


class CloseLive(View):
    """关闭直播"""

    def post(self, request):
        try:
            lr = LiveRoom.objects.get(user=request.user)
        except:
            return JsonResponse({
                'status': 'fail',
                'msg': '参数错误'
            })
        # 踢流  rtmp://192.168.3.41/live/?token=1676327eede5c1f1e4f54ebf6570b62a
        if lr.live_stream and lr.live_key:
            stream = RTMP_ADDRESS + lr.live_stream
            delete_stream(stream)

        # 关闭直播
        lr.live_key = None
        lr.live_stream = None
        lr.is_open = False
        lr.save()
        return JsonResponse({
            'status': 'success'
        })
